﻿/*
--------------------------------------
File: FastMedianFilter.cs
Project: Themaopdracht 7
Author: Maarten Kroon

Description:
A fast median filter based on histograms which filters the image based on a dynamic filter size
--------------------------------------
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace THO7_Team8
{
    class FastMedianFilter : VisionAlgorithm
    {
        private int filterSize;
        public FastMedianFilter(String name)
            : base(name)
        {

            hasConfiguration = true;
            configuration = new MedianFilterConfiguration();
        }

        public override System.Drawing.Bitmap DoAlgorithm(System.Drawing.Bitmap sourceImage)
        {
            filterSize = _configValue;
            Console.WriteLine("Used Value: " + filterSize);
            Bitmap returnImage = new Bitmap(sourceImage);
            int[] rgbValues = MyImage.BmpToArray(returnImage);

            //Modified pixelArray        
            int[] rgbValues2 = new int[rgbValues.Length];

            int width = sourceImage.Width;
            int height = sourceImage.Height;

            for (int i = ((width) + 1) * (filterSize / 2); i < ((width) * height) - (width + 1) * (filterSize / 2); i++)
            {
                //Arrays for each of the color channels
                int[] blueArray = new int[9];
                int[] greenArray = new int[9];
                int[] redArray = new int[9];
                int[] tempBlueArray = new int[256];
                int[] tempGreenArray = new int[256];
                int[] tempRedArray = new int[256];

                if (i % (width) < (filterSize / 2) || i % (width) == (width) - (filterSize / 2))
                {
                    //Skip the first and last pixels depending on the filter size
                    rgbValues2[i] = rgbValues[i];
                }
                //Loops through the filter
                for (int y = (-(filterSize / 2)); y <= (filterSize / 2); y++)
                {
                    for (int x = (-(filterSize / 2)); x <= (filterSize / 2); x++)
                    {
                        //Fils the arrays
                        tempBlueArray[rgbValues[i + x + (y * (width))] & 255]++;
                        tempGreenArray[(rgbValues[i + x + (y * (width))] >> 8) & 255]++;
                        tempRedArray[(rgbValues[i + x + (y * (width))] >> 16) & 255]++;
                    }
                }

                int counter = 0;
                for(int j = 0; i < 256; i++)
                {
                    if (tempBlueArray[j] != 0) 
                    {
                        blueArray[counter] = tempBlueArray[j];
                        counter ++;
                    }
                }
                counter = 0;
                for(int j = 0; i < 256; i++)
                {
                    if (tempGreenArray[j] != 0) 
                    {
                        greenArray[counter] = tempGreenArray[j];
                        counter ++;
                    }
                }
                counter = 0;
                for(int j = 0; i < 256; i++)
                {
                    if (tempRedArray[j] != 0) 
                    {
                        redArray[counter] = tempRedArray[j];
                        counter ++;
                    }
                }   
                //Creates the color for the int
                rgbValues2[i] = 255 << 24 | (Convert.ToByte(redArray[4]) << 16) | (Convert.ToByte(greenArray[4]) << 8) | Convert.ToByte(blueArray[4]);
            }

            //Returns the modified image
            returnImage = MyImage.ArrayToBmp(rgbValues2, returnImage);
            Bitmap orignalImage = new Bitmap(sourceImage);
            //FilterTest.MedianTest(orignalImage, returnImage, 3);
            return returnImage;

            
            
        }
    }
}






